/***************************************** 
 * Desc: UGUI编辑器新建对象工具
 * @Author: GSan
 * @Email: 2087653648@qq.com
 * CreateDate: 2020-07-11 16:57:32
*****************************************/

using Common.UGUI.Base;
using Common.UGUI.Base.Data;
using Common.UGUI.View;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;

namespace Common.UserEditor.UGUIViewSpace {

    public class UGUICustomEditorMenu : Editor {


        #region 域

        /* 一下都是默认的UGUI新建对象名字 */
        public const string UGUIRootDefaultName = "UGUIRoot";
        public const string UGUICanvasDefaultName = "UGUICanvas";
        public const string UGUIPanelDefaultName = "UGUIPanel";
        public const string UGUIImageDefaultName = "UGUIImage";
        public const string UGUIButtonDefaultName = "UGUIButton";
        public const string UGUITextDefaultName = "UGUIText";
        public const string UGUIScrollerDefaultName = "UGUIScroller";

        private static UGUIBaseData _dataComponent = null;

        #endregion

        #region UGUIRoot

        [MenuItem("GameObject/UI/ThirdParty/UGUI/Root")]
        public static UGUIRoot CheckAndCreateUGUIRoot() {

            GameObject root = GameObject.Find(UGUIRootDefaultName);

            UGUIRoot uguiRoot = null;

            if (root == null) {

                root = new GameObject();

                uguiRoot = root.AddComponent<UGUIRoot>();

                uguiRoot.SetEditorName(UGUIRootDefaultName);

            } else {

                uguiRoot = root.GetComponent<UGUIRoot>();

                if (uguiRoot == null) {

                    uguiRoot = root.AddComponent<UGUIRoot>();

                    uguiRoot.SetEditorName(UGUIRootDefaultName);
                } else {

                    Debug.LogError("Already has UGUIRoot.");
                }
            }

            return uguiRoot;
        }

        private static UGUIRoot FetchUGUIRoot() {

            GameObject root = GameObject.Find(UGUIRootDefaultName);

            UGUIRoot uguiRoot = null;

            if (root == null) {

                root = new GameObject();

                uguiRoot = root.AddComponent<UGUIRoot>();

                uguiRoot.SetEditorName(UGUIRootDefaultName);

            } else {

                uguiRoot = root.GetComponent<UGUIRoot>();

                if (uguiRoot == null) {

                    uguiRoot = root.AddComponent<UGUIRoot>();

                    uguiRoot.SetEditorName(UGUIRootDefaultName);
                }
            }

            return uguiRoot;
        }

        #endregion

        #region UGUICanvas

        [MenuItem("GameObject/UI/ThirdParty/UGUI/Canvas")]
        public static UGUICanvas NewCanvas() {

            TryLoadDataPrefab();

            if (_dataComponent != null) {

                UGUIRoot root = FetchUGUIRoot();

                GameObject go = new GameObject();

                go.AddComponent<Canvas>();
                go.AddComponent<CanvasScaler>();
                go.AddComponent<GraphicRaycaster>();

                UGUICanvas canvas = go.AddComponent<UGUICanvas>();

                canvas.Canvas.renderMode = RenderMode.ScreenSpaceOverlay;

                canvas.CanvasScaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
                canvas.CanvasScaler.referenceResolution = new Vector2(_dataComponent.ResolutionX, _dataComponent.ResolutionY);

                canvas.SetEditorName(UGUICanvasDefaultName);

                canvas.SetParent(root);

                return canvas;
            } else {

                return null;
            }
        }

        #endregion

        #region UGUIPanel

        [MenuItem("GameObject/UI/ThirdParty/UGUI/Panel")]
        public static UGUIPanel NewPanel() {

            UGUIView parentView = FetchUGUIViewBySelection();

            if (parentView == null || parentView is UGUIRoot) {

                UGUIRoot root = FetchUGUIRoot();

                int childrenCount = root.Transform.childCount;

                UGUICanvas canvas = null;

                for (int i = 0; i < childrenCount; ++i) {

                    canvas = root.Transform.GetChild(i).GetComponent<UGUICanvas>();

                    if (canvas != null) {

                        break;
                    }
                }

                if (canvas == null) {

                    canvas = NewCanvas();
                }

                parentView = canvas;
            }

            GameObject go = new GameObject();
            UGUIPanel panel = go.AddComponent<UGUIPanel>();
            panel.SetEditorName(UGUIPanelDefaultName);
            panel.SetParent(parentView);
            panel.SetColor(Color.clear);
            return panel;
        }

        #endregion

        #region UGUIImage

        [MenuItem("GameObject/UI/ThirdParty/UGUI/Image")]
        public static void NewImage() {

            UGUIView parentView = FetchUGUIViewBySelection();

            if (parentView == null || parentView is UGUIRoot) {

                UGUIRoot root = FetchUGUIRoot();

                int childrenCount = root.Transform.childCount;

                UGUICanvas canvas = null;

                for (int i = 0; i < childrenCount; ++i) {

                    canvas = root.Transform.GetChild(i).GetComponent<UGUICanvas>();

                    if (canvas != null) {

                        break;
                    }
                }

                if (canvas == null) {

                    canvas = NewCanvas();
                }

                parentView = canvas;
            }

            GameObject go = new GameObject();
            UGUIImage image = go.AddComponent<UGUIImage>();
            image.SetEditorName(UGUIImageDefaultName);
            image.SetParent(parentView);
        }

        #endregion

        #region UGUIButton

        [MenuItem("GameObject/UI/ThirdParty/UGUI/Button")]
        public static void NewButton() {

            UGUIView parentView = FetchUGUIViewBySelection();

            if (parentView == null || parentView is UGUIRoot) {

                UGUIRoot root = FetchUGUIRoot();

                int childrenCount = root.Transform.childCount;

                UGUICanvas canvas = null;

                for (int i = 0; i < childrenCount; ++i) {

                    canvas = root.Transform.GetChild(i).GetComponent<UGUICanvas>();

                    if (canvas != null) {

                        break;
                    }
                }

                if (canvas == null) {

                    canvas = NewCanvas();
                }

                parentView = canvas;
            }

            GameObject go = new GameObject();
            //TODO:看起来，原来的框架是跳开了UGUI.Button，自己定义。。。。这里补一下，不一定和原来效果一样
            var button = go.AddComponent<Button>();
            //UGUIButton button = go.AddComponent<UGUIButton>();
            //button.SetIsInteractable(true);
            //button.SetEditorName(UGUIButtonDefaultName);
            //button.SetParent(parentView);
            ////默认配一个文本文件
            //GameObject textGO = new GameObject("Text");
            //textGO.transform.position = Vector3.zero;
            //textGO.transform.SetParent(button.Transform, false);
            //Text text = textGO.AddComponent<Text>();
            //text.text = "UGUIButton";
            //text.color = Color.black;
        }

        #endregion

        #region UGUIText

        [MenuItem("GameObject/UI/ThirdParty/UGUI/Text")]
        public static void NewText() {

            UGUIView parentView = FetchUGUIViewBySelection();

            if (parentView == null || parentView is UGUIRoot || parentView is UGUICanvas) {

                UGUIRoot root = FetchUGUIRoot();

                int childrenCount = root.Transform.childCount;

                UGUICanvas canvas = null;

                for (int i = 0; i < childrenCount; ++i) {

                    canvas = root.Transform.GetChild(i).GetComponent<UGUICanvas>();

                    if (canvas != null) {

                        break;
                    }
                }

                if (canvas == null) {

                    canvas = NewCanvas();
                }

                UGUIPanel panel = null;

                childrenCount = canvas.Transform.childCount;

                for (int i = 0; i < childrenCount; ++i) {

                    panel = canvas.Transform.GetChild(i).GetComponent<UGUIPanel>();

                    if (panel != null) {

                        break;
                    }
                }

                if (panel == null) {

                    panel = NewPanel();
                }

                parentView = panel;
            }

            GameObject go = new GameObject();
            UGUIText text = go.AddComponent<UGUIText>();
            text.SetEditorName(UGUITextDefaultName);
            text.SetParent(parentView);
        }

        #endregion

        #region UGUIScroller

        [MenuItem("GameObject/UI/ThirdParty/UGUI/Scroller")]
        public static UGUIPanel NewScroller() {

            UGUIView parentView = FetchUGUIViewBySelection();

            if (parentView == null || parentView is UGUIRoot) {

                UGUIRoot root = FetchUGUIRoot();

                int childrenCount = root.Transform.childCount;

                UGUICanvas canvas = null;

                for (int i = 0; i < childrenCount; ++i) {

                    canvas = root.Transform.GetChild(i).GetComponent<UGUICanvas>();

                    if (canvas != null) {

                        break;
                    }
                }

                if (canvas == null) {

                    canvas = NewCanvas();
                }

                parentView = canvas;
            }

            GameObject go = new GameObject();
            UGUIScroller scroller = go.AddComponent<UGUIScroller>();
            scroller.SetEditorName(UGUIScrollerDefaultName);
            scroller.SetParent(parentView);
            scroller.SetIsInteractable(true);
            scroller.SetColor(Color.clear);
            scroller.IfPanelSizeAffectContent = true;
            return scroller;
        }

        #endregion

        #region 私有方法

        private static void TryLoadDataPrefab() {

            if (_dataComponent == null) {

                GameObject dataPrefa = AssetDatabase.LoadAssetAtPath<GameObject>(UGUIBaseDataWindow.DataPrefabPath);

                AssetDatabase.Refresh();

                if (dataPrefa != null) {

                    _dataComponent = dataPrefa.GetComponent<UGUIBaseData>();

                    if (_dataComponent == null) {

                        Debug.LogError("UGUIResEditWindow: DataPrefabPath " + UGUIBaseDataWindow.DataPrefabPath + " has GameObject without UGUIBaseData component.");
                    }
                } else {

                    Debug.LogError("UGUIResEditWindow: DataPrefabPath " + UGUIBaseDataWindow.DataPrefabPath + " has no target GameObject.");
                }
            }
        }

        private static UGUIView FetchUGUIViewBySelection() {

            if (Selection.activeTransform != null) {

                Transform parent = Selection.activeTransform;
                UGUIView selectedView = null;

                while (parent != null) {

                    selectedView = parent.GetComponent<UGUIView>();

                    if (selectedView != null) {

                        break;
                    }

                    parent = parent.parent;
                }

                if (selectedView == null) {

                    Debug.Log("<color=#ff0000> Selected GameObject and it's tree could't find any UGUIView component.</color>");
                }

                return selectedView;
            }

            return null;
        }

        #endregion
    }
}
